/*
 * Copyright (C) 2009-2011 Knowings
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 3
 * as published by the Free Software Foundation.
 *

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package com.knowings.tbs;

import java.io.Serializable;
import java.lang.reflect.Array;

import com.knowings.tbs.auth.BadCredentialsException;
import com.knowings.tbs.auth.ICredentials;

/**
 * The entry point into the trace repository.
 * Represents the entry point into the trace repository. Typically the object
 * implementing this interface will be acquired from a JNDI-compatible naming and directory service
 * of as a Spring bean.
 * 
 * @author privarola
 */
public interface ITBSKernel {

  /** Current version of this implementation. 
   */
  static final String SPEC_VERSION = "0.5";

  /** Header for those constants. 
   */
  static final String SPEC_NAMESPACE_HEADER = "http://www.knowings.com/jtr/" + SPEC_VERSION;

  /**
   * The descriptor key for the version of the specification
   * that this repository implements.
   */
  public static final String SPEC_VERSION_DESC = SPEC_NAMESPACE_HEADER + "/specification/version";

  /**
   * The descriptor key for the name of the specification
   * that this repository implements.
   */
  public static final String SPEC_NAME_DESC = SPEC_NAMESPACE_HEADER + "/specification/name";

  /**
   * The descriptor key for the name of the repository vendor.
   */
  public static final String REP_VENDOR_DESC = SPEC_NAMESPACE_HEADER + "/repository/vendor/name";

  /**
   * The descriptor key for the URL of the repository vendor.
   */
  public static final String REP_VENDOR_URL_DESC = SPEC_NAMESPACE_HEADER + "/repository/vendor/url";

  /**
   * The descriptor key for the name of this repository implementation.
   */
  public static final String REP_NAME_DESC = SPEC_NAMESPACE_HEADER + "/repository/name";

  /**
   * The descriptor key for the version of this repository implementation.
   */
  public static final String REP_VERSION_DESC = SPEC_NAMESPACE_HEADER + "/repository/version";

  /**
   * The presence of this key indicates that this implementation supports
   * all level 1 features. This key will always be present.
   */
  public static final String LEVEL_1_SUPPORTED = SPEC_NAMESPACE_HEADER + "/level/1";

  /**
   * The presence of this key indicates that this implementation supports
   * all level 2 features.
   */
  public static final String LEVEL_2_SUPPORTED = SPEC_NAMESPACE_HEADER + "/level/2";

  /**
   * The presence of this key indicates that this implementation supports
   * all level 3 features.
   */
  public static final String LEVEL_3_SUPPORTED = SPEC_NAMESPACE_HEADER + "/level/3";

  /**
   * The presence of this key indicates that this implementation supports
   * all level 4 features. It should not be the case at this time.
   */
  public static final String LEVEL_4_SUPPORTED = SPEC_NAMESPACE_HEADER + "/level/4";

  /**
   * The presence of this key indicates that this implementation supports transactions.
   */
  public static final String OPTION_TRANSACTIONS_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/transactions";

  /**
   * The presence of this key indicates that this implementation supports permissions.
   */
  public static final String OPTION_PERMISSIONS_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/permissions";

  /**
   * The presence of this key indicates that this implementation supports observation.
   */
  public static final String OPTION_OBSERVATION_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/observation";

  /**
   * The presence of this key indicates that this implementation also provides REST access.
   */
  public static final String OPTION_REST_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/rest";

  /**
   * The presence of this key indicates that this implementation also provides XMPP access.
   */
  public static final String OPTION_XMPP_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/xmpp";

  /**
   * The presence of this key indicates that this implementation supports triggering transformations.
   */
  public static final String OPTION_TRIGGERS_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/triggers";

  /**
   * The presence of this key indicates that null attributes or parameters are supported
   */
  public static final String OPTION_NULL_PROPS_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/null_props";

  /**
   * The presence of this key indicates that multi-valued attributes or parameters are supported
   */
  public static final String OPTION_MULTIVALUED_PROPS_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/multivalued_props";

  /**
   * The presence of this key indicates that empty lists are acceptable values for attributes or parameters.
   * An empty list will be considered as a multiple value of size 0, different from a null value. 
   */
  public static final String OPTION_EMPTY_MULTIVALUED_PROPS_SUPPORTED = SPEC_NAMESPACE_HEADER
      + "/option/empty_multivalued_props";

  /**
   * The presence of this key indicates that multi-valued attributes or parameters order is kept.
   */
  public static final String OPTION_ORDERED_MULTIVALUED_PROPS_SUPPORTED = SPEC_NAMESPACE_HEADER
      + "/option/multivalued_ordered_props";

  /**
   * The presence of this key indicates that trace import from text files is supported. The supported formats
   * are described in separate descriptors.
   */
  public static final String OPTION_BULK_IMPORT_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/bulk_import";

  /**
   * The presence of this key indicates that queries can be run considering all traces as input, 
   * without specifying their UID.
   */
  public static final String OPTION_GLOBAL_QUERIES_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/global_queries";

  /**
   * The presence of this key indicates that transformations can be run considering all traces as input, 
   * without specifying their UID. Level 2 compliance is required.
   */
  public static final String OPTION_GLOBAL_TRANSFORMATIONS_SUPPORTED = SPEC_NAMESPACE_HEADER
      + "/option/global_transformations";

  /**
   * The presence of this key indicates that the execution of incremental transformations is supported.
   */
  public static final String OPTION_INCREMENTAL_TRANSFORMATIONS_SUPPORTED = SPEC_NAMESPACE_HEADER
      + "/option/incremental_transformations";

  /**
   * The presence of this key indicates that it is possible to navigate through the subtraces of a Trace 
   * that has been split according time ranges. In this case each part knows its following (of preceding) 
   * part in the global Trace.
   */
  public static final String OPTION_CHAINING_TRACES_SUPPORTED = SPEC_NAMESPACE_HEADER + "/option/chaining_traces";

  /**
   * The presence of this key indicates that the JPA-QL query language is supported.
   */
  public static final String QUERY_LANGAGE_JPAQL_SUPPORTED = SPEC_NAMESPACE_HEADER + "/query/language/jpa-ql";

  /**
   * The presence of this key indicates that the standard XML export format is supported.
   */
  public static final String EXPORT_FORMAT_XML_SUPPORTED = SPEC_NAMESPACE_HEADER + "/export/format/xml";

  /**
   * The presence of this key indicates that import in the standard XML format is supported.
   */
  public static final String IMPORT_FORMAT_XML_SUPPORTED = SPEC_NAMESPACE_HEADER + "/import/format/xml";

  /**
   * The presence of this key indicates that the JavaScript language is supported to perform transformations.
   */
  public static final String TRANSFORMATION_LANGUAGE_JAVASCRIPT_SUPPORTED = SPEC_NAMESPACE_HEADER
      + "/transformation/language/javascript";

  /**
   * The constant for the JPA-QL query language that is the default query language for level 1 implementations. 
   */
  public static final String LANGAGE_JPAQL = "application/x-jpaql";

  /**
   * The constant for the JavaScript transformation language that is the default transformation language for level 2 implementations. 
   */
  public static final String LANGAGE_JAVASCRIPT = "application/javascript";

  /**
   * The constant for the standard XML output format.
   */
  public static final String XML_FORMAT = "text/xml";

  /**
   * Returns a string array holding all descriptor keys available for this implementation.
   * This set must contain at least the built-in keys defined by the string constants in
   * this interface.Used in conjunction with {@link #getDescriptor(String name)}
   * to query information about this repository implementation.
   * @return an {@link Array} of {@link String} representing the available keys.
   */
  public String[] getDescriptorKeys();

  /**
   * Returns the descriptor for the specified key. Used to query information about this
   * repository implementation. The set of available keys can be found by calling
   * {@link #getDescriptorKeys}. If the specified key is not found, <code>null</code> is returned.
   *
   * @param key a string corresponding to a descriptor for this repository implementation.
   * @return a descriptor value
   */
  public Serializable getDescriptor(String key);

  /**
   * Authenticates the user using the supplied <code>credentials</code>.
   * <p>
   * If <code>workspaceName</code> is recognized as the name of an existing workspace in the trace repository and
   * authorization to access that workspace is granted, then a new <code>ISession</code> object is returned.
   * The format of the string <code>workspaceName</code> depends upon the implementation.
   * <p>
   * If <code>credentials</code> is <code>null</code>, it is assumed that authentication is handled by a
   * mechanism external to the repository itself (for example, through the JAAS framework) and that the
   * repository implementation exists within a context (for example, an application server) that allows
   * it to handle authorization of the request for access to the specified workspace.
   * <p>
   * If <code>workspaceName</code> is <code>null</code>, a default workspace is automatically selected by
   * the repository implementation. This may, for example, be the "home workspace" of the user whose
   * credentials were passed, though this is entirely up to the configuration and implementation of the
   * repository.
   * <p>
   * If authentication or authorization for the specified workspace fails, a <code>BadCredentialsException</code> is
   * thrown.
   * <p>
   * If <code>workspaceName</code> is not recognized, a <code>NoSuchWorkspaceException</code> is thrown.
   *
   * @param credentials   The credentials of the user
   * @param workspaceName the name of a workspace.
   * @return a valid session for the user to access the repository.
   * @throws BadCredentialsException  If the login fails.
   * @throws NoSuchWorkspaceException If the specified <code>workspaceName</code> is not recognized.
   */
  public ISession login(ICredentials credentials, String workspaceName) throws BadCredentialsException,
      NoSuchWorkspaceException;

  /**
   * Equivalent to <code>login(null, null)</code>.
   *
   * @return a valid session for the user to access the repository.
   * @throws BadCredentialsException  If the login authentication fails.
   */
  public ISession login() throws BadCredentialsException;

  /**
   * Returns all names of accessible workspaces contained in this trace repository
   * @return all names of accessible workspaces contained in this trace repository
   */
  public String[] getWorkspaceNames();
}
